from __future__ import annotations

from typing import Any

import gdb  # type: ignore


def value_to_python(value: gdb.Value, _depth: int = 0) -> Any:
    """
    Convert a gdb.Value into JSON-serializable Python data.

    Parameters
    ----------
    value : gdb.Value
        The GDB value to convert.
    _depth : int
        Internal recursion guard to avoid infinite loops.

    Returns
    -------
    Any
        JSON-serializable representation.
    """
    MAX_DEPTH = 5
    if _depth > MAX_DEPTH:
        return str(value)

    try:
        code = value.type.code
    except Exception:
        return str(value)

    try:
        if code in (gdb.TYPE_CODE_INT, gdb.TYPE_CODE_ENUM):
            return int(value)
        if code == gdb.TYPE_CODE_BOOL:
            return bool(int(value))
        if code == gdb.TYPE_CODE_FLT:
            return float(value)
        if code == gdb.TYPE_CODE_STRING:
            return value.string()
        if code == gdb.TYPE_CODE_CHAR:
            return chr(int(value) & 0xFF)
        if code == gdb.TYPE_CODE_PTR:
            try:
                return int(value)
            except Exception:
                return str(value)
        if code == gdb.TYPE_CODE_REF:
            try:
                return value_to_python(value.referenced_value(), _depth + 1)
            except Exception:
                return str(value)
        if code == gdb.TYPE_CODE_ARRAY:
            items = []
            try:
                for element in value:
                    items.append(value_to_python(element, _depth + 1))
                return items
            except Exception:
                return str(value)
        if code in (gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION):
            return str(value)
    except Exception:
        return str(value)

    # Fallback for any unhandled type codes.
    return str(value)